package com.tree.backend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tree.backend.entity.dto.department.DepartmentDTO;
import com.tree.backend.entity.dto.department.DepartmentQueryDTO;
import com.tree.backend.entity.pojo.Department;
import com.tree.backend.entity.pojo.User;
import com.tree.backend.entity.vo.department.DepartmentTreeVO;
import com.tree.backend.entity.vo.department.DepartmentVO;
import com.tree.backend.mapper.DepartmentMapper;
import com.tree.backend.mapper.UserMapper;
import com.tree.backend.service.IDepartmentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * <p>
 * 部门组织表 服务实现类
 * </p>
 */
@Service
@RequiredArgsConstructor
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department> implements IDepartmentService {

    private final DepartmentMapper departmentMapper;
    
    private final UserMapper userMapper;

    @Override
    public IPage<DepartmentVO> getDepartmentList(DepartmentQueryDTO queryDTO) {
        // 创建分页对象
        Page<Department> page = new Page<>(queryDTO.getPage(), queryDTO.getPageSize());
        
        // 构建查询条件
        QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
        if (StringUtils.hasText(queryDTO.getDeptName())) {
            queryWrapper.like("dept_name", queryDTO.getDeptName());
        }
        if (StringUtils.hasText(queryDTO.getDeptCode())) {
            queryWrapper.like("dept_code", queryDTO.getDeptCode());
        }
        if (queryDTO.getStatus() != null) {
            queryWrapper.eq("status", queryDTO.getStatus());
        }
        queryWrapper.orderByAsc("sort_order");
        
        // 查询数据
        Page<Department> departmentPage = departmentMapper.selectPage(page, queryWrapper);
        
        // 转换为VO
        return departmentPage.convert(this::convertToVO);
    }

    @Override
    public DepartmentVO getDepartmentDetail(Long id) {
        Department department = departmentMapper.selectById(id);
        if (department == null) {
            return null;
        }
        return convertToVO(department);
    }

    @Override
    public DepartmentVO addDepartment(DepartmentDTO departmentDTO) {
        // 校验部门编码唯一性
        QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("dept_code", departmentDTO.getDeptCode());
        if (departmentMapper.selectCount(queryWrapper) > 0) {
            throw new RuntimeException("部门编码已存在");
        }
        
        // 校验部门名称
        // 判断空
        if (!StringUtils.hasText(departmentDTO.getDeptName())) {
            throw new RuntimeException("部门名称不能为空");
        }
        
        // 创建部门对象
        Department department = new Department();
        BeanUtils.copyProperties(departmentDTO, department);
        
        // 设置默认值
        if (department.getParentId() == null) {
            department.setParentId(0L); // 设置为顶级部门
        }
        if (department.getStatus() == null) {
            department.setStatus((byte) 1); // 默认启用
        }
        if (department.getSortOrder() == null) {
            department.setSortOrder(0); // 默认排序号
        }
        
        // 保存部门
        departmentMapper.insert(department);
        
        // 返回VO
        return convertToVO(department);
    }

    @Override
    public DepartmentVO updateDepartment(Long id, DepartmentDTO departmentDTO) {
        // 检查部门是否存在
        Department department = departmentMapper.selectById(id);
        if (department == null) {
            return null;
        }
        
        // 更新部门信息
        BeanUtils.copyProperties(departmentDTO, department);
        department.setId(id);
        
        // 保存更新
        departmentMapper.updateById(department);
        
        // 返回VO
        return convertToVO(department);
    }

    @Override
    public boolean deleteDepartment(Long id) {
        // 检查是否有子部门
        QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", id);
        if (departmentMapper.selectCount(queryWrapper) > 0) {
            return false; // 有子部门，不允许删除
        }
        
        // 删除部门
        return departmentMapper.deleteById(id) > 0;
    }

    @Override
    public List<DepartmentVO> getAllDepartments() {
        // 查询所有启用状态的部门
        QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1) // 只查询启用状态的部门
                   .orderByAsc("sort_order"); // 按排序号排序
        
        List<Department> departments = departmentMapper.selectList(queryWrapper);
        
        // 转换为VO列表
        return departments.stream()
                .map(this::convertToVO)
                .collect(java.util.stream.Collectors.toList());
    }

    @Override
    public List<DepartmentTreeVO> getDepartmentTree() {
        // 查询所有部门
        List<Department> departments = departmentMapper.selectList(null);
        
        // 构建部门映射
        Map<Long, DepartmentTreeVO> departmentMap = new HashMap<>();
        List<DepartmentTreeVO> rootDepartments = new ArrayList<>();
        
        // 转换为树节点并查找根节点
        for (Department department : departments) {
            DepartmentTreeVO treeVO = new DepartmentTreeVO();
            BeanUtils.copyProperties(department, treeVO);
            treeVO.setChildren(new ArrayList<>());
            
            // 获取负责人名称
            if (department.getManagerId() != null) {
                User user = userMapper.selectById(department.getManagerId());
                if (user != null) {
                    treeVO.setManagerName(user.getUsername());
                }
            }
            
            departmentMap.put(department.getId(), treeVO);
            
            // 查找根节点（parentId为0或null的部门）
            if (department.getParentId() == null || department.getParentId() == 0) {
                rootDepartments.add(treeVO);
            }
        }
        
        // 构建树结构
        for (Department department : departments) {
            if (department.getParentId() != null && department.getParentId() != 0) {
                DepartmentTreeVO parentNode = departmentMap.get(department.getParentId());
                DepartmentTreeVO childNode = departmentMap.get(department.getId());
                if (parentNode != null && childNode != null) {
                    parentNode.getChildren().add(childNode);
                }
            }
        }
        
        // 对子部门排序
        sortDepartmentTree(rootDepartments);
        
        return rootDepartments;
    }
    
    /**
     * 将Department转换为DepartmentVO
     */
    private DepartmentVO convertToVO(Department department) {
        DepartmentVO vo = new DepartmentVO();
        BeanUtils.copyProperties(department, vo);
        
        // 获取上级部门名称
        if (department.getParentId() != null && department.getParentId() != 0) {
            Department parent = departmentMapper.selectById(department.getParentId());
            if (parent != null) {
                vo.setParentName(parent.getDeptName());
            } else {
                vo.setParentName("无");
            }
        } else {
            vo.setParentName("无");
        }
        
        // 获取负责人名称
        if (department.getManagerId() != null) {
            User user = userMapper.selectById(department.getManagerId());
            if (user != null) {
                vo.setManagerName(user.getUsername());
            }
        }
        
        return vo;
    }
    
    /**
     * 递归排序部门树
     */
    private void sortDepartmentTree(List<DepartmentTreeVO> departments) {
        if (departments == null || departments.isEmpty()) {
            return;
        }
        
        // 按排序号排序
        departments.sort(Comparator.comparingInt(DepartmentTreeVO::getStatus)
                .thenComparingInt(DepartmentTreeVO::getSortOrder));
        
        // 递归排序子部门
        for (DepartmentTreeVO department : departments) {
            sortDepartmentTree(department.getChildren());
        }
    }
}
